package com.hsjk.szwj.module.pay.controller.app.order;

import cn.hutool.core.util.ObjectUtil;
import com.hsjk.szwj.framework.common.exception.ServiceException;
import com.hsjk.szwj.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.hsjk.szwj.framework.common.util.spring.SpringBeansUtil;
import com.hsjk.szwj.module.pay.constant.PayOrderConstant;
import com.hsjk.szwj.module.pay.controller.AbstractPayOrderController;
import com.hsjk.szwj.module.pay.controller.app.order.vo.ClosePayOrderReqVO;
import com.hsjk.szwj.module.pay.controller.app.order.vo.ClosePayOrderRespVO;
import com.hsjk.szwj.module.pay.dal.dataobject.CommonPayResult;
import com.hsjk.szwj.module.pay.dal.dataobject.config.ChannelRetMsg;
import com.hsjk.szwj.module.pay.dal.dataobject.config.MchAppConfigContext;
import com.hsjk.szwj.module.pay.dal.dataobject.order.PayOrderDO;
import com.hsjk.szwj.module.pay.dal.dataobject.system.MchAppDO;
import com.hsjk.szwj.module.pay.dal.dataobject.system.MchInfoDO;
import com.hsjk.szwj.module.pay.service.ConfigContextQueryService;
import com.hsjk.szwj.module.pay.service.IMchAppService;
import com.hsjk.szwj.module.pay.service.IMchInfoService;
import com.hsjk.szwj.module.pay.service.IPayOrderCloseService;
import com.hsjk.szwj.module.pay.service.PayInterfaceDefineService;
import com.hsjk.szwj.module.pay.service.PayOrderService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author chenjiawei
 * @desc
 * @Date 2023/08/24 14:56
 **/
@Tag(name = "应用端 - 关闭订单相关接口")
@RestController
@RequestMapping("/pay")
@Validated
@Slf4j
public class CloseOrderController extends AbstractPayOrderController {
    @Resource
    private PayOrderService payOrderService;
    @Resource
    private ConfigContextQueryService configContextQueryService;
    @Resource
    private PayInterfaceDefineService payInterfaceDefineService;
    @Resource
    private IMchInfoService mchInfoService;
    @Resource
    private IMchAppService mchAppService;

    /**
     * @author: xiaoyu
     * @date: 2022/1/25 9:19
     * @describe: 关闭订单
     */
    @RequestMapping("/close")
    public CommonPayResult queryOrder() {

        //获取参数 & 验签
        ClosePayOrderReqVO rq = getRQByWithMchSign(ClosePayOrderReqVO.class);

        if (ObjectUtil.isNotNull(rq.getMchOrderId())
                && ObjectUtil.isNotNull(rq.getPayOrderId())) {
            throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),
                    "mchOrderNo 和 payOrderId 不能同时为空");
        }
        MchInfoDO mchInfo = mchInfoService.getMchInfoById(rq.getMchId());
        PayOrderDO payOrder = payOrderService.queryMchOrder(mchInfo.getId(),
                rq.getPayOrderId(), rq.getMchOrderId());
        if (payOrder == null) {
            throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),
                    "订单不存在");
        }

        if (payOrder.getState() != PayOrderConstant.STATE_INIT && payOrder.getState()
                != PayOrderConstant.STATE_ING) {
            throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),
                    "当前订单不可关闭");
        }

        ClosePayOrderRespVO bizRes = new ClosePayOrderRespVO();

        // 订单生成状态  直接修改订单状态
        if (payOrder.getState() == PayOrderConstant.STATE_INIT) {
            payOrderService.updateInit2Close(payOrder.getId());
            bizRes.setChannelRetMsg(ChannelRetMsg.confirmSuccess(null));
            return CommonPayResult.okWithSign(bizRes,
                    configContextQueryService.queryMchApp(rq.getMchId(), rq.getAppId())
                            .getAppSecret());
        }

        try {

            Long payOrderId = payOrder.getId();
            String ifCode = payInterfaceDefineService.getCodeById(payOrderId);
            //查询支付接口是否存在
            IPayOrderCloseService closeService =
                    SpringBeansUtil.getBean(ifCode + "PayOrderCloseService", IPayOrderCloseService.class);

            // 支付通道接口实现不存在
            if (closeService == null) {
                log.error("{} interface not exists!", payOrder.getIfId());
                return null;
            }
            MchAppDO mchAppDO = mchAppService.getById(payOrder.getAppId());
            //查询出商户应用的配置信息
            MchAppConfigContext mchAppConfigContext =
                    configContextQueryService.queryMchInfoAndAppInfo(mchInfo.getId(),
                            mchAppDO.getId());

            ChannelRetMsg channelRetMsg = closeService.close(payOrder, mchAppConfigContext);
            if (channelRetMsg == null) {
                log.error("channelRetMsg is null");
                return null;
            }

            log.info("关闭订单[{}]结果为：{}", payOrderId, channelRetMsg);

            // 关闭订单 成功
            if (channelRetMsg.getChannelState() == ChannelRetMsg.ChannelState.CONFIRM_SUCCESS) {
                payOrderService.updateIng2Close(payOrderId);
            } else {
                return CommonPayResult.error(channelRetMsg.getChannelErrMsg());
            }

            bizRes.setChannelRetMsg(channelRetMsg);
        } catch (Exception e) {  // 关闭订单异常
            log.error("error payOrderId = {}", payOrder.getIfId(), e);
            return null;
        }

        return CommonPayResult.okWithSign(bizRes,
                configContextQueryService.queryMchApp(rq.getMchId(),
                        rq.getAppId()).getAppSecret());
    }

}
